package com.ctec;

import com.ctec.config.MinioProperties;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDate;


@Slf4j
@Service
public class FileService {

    @Resource
    private MinioClient minioClient;

    @Resource
    private MinioProperties minioProperties;


    public InputStream downloadFile(String bucketName, String objectName) throws Exception {
        return minioClient.getObject(// 调用 MinIO 客户端的 getObject 方法，获取指定对象的输入流
                GetObjectArgs.builder()// 构建 GetObjectArgs 对象
                        .bucket(bucketName)// 设置桶名
                        .object(objectName)// 设置对象名
                        .build()); // 构建参数并调用 getObject

    }





    //生成文件全路径
    private String getObjectName(String fileName) {
        String prefixPath = "web/upload/";
        return prefixPath + fileName;
    }

    //根据日期生成路径结构
    private String getObjectNameByDate(String fileName) {
        LocalDate now = LocalDate.now();
        String year = String.valueOf(now.getYear());
        String month = String.format("%02d", now.getMonthValue());
        String day = String.format("%02d", now.getDayOfMonth());
        String prefixPath = "web/upload/" + year + "/" + month + "/" + day + "/";
        return prefixPath + fileName;
    }

    //根据文件全路径获取文件的预下载链接，文件的下载通过预签名的url
    public String fetchFilePreDownloadUrl(String objectName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        String url =
            minioClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(minioProperties.getBucketName())
                    .object(objectName)
                    .expiry(60 * 60 * 24)
                    .build());
        log.info("文件预下载路径：{} - 链接有效时间：24小时", url);
        return url;
    }

    //  文件下载方式二 通过流直接下载
    public void downloadStream(String fileName, HttpServletResponse response)
        throws ServletException, IOException {

        try {
            GetObjectArgs build = GetObjectArgs.builder().bucket(minioProperties.getBucketName()).object(fileName).build();
            InputStream stream = minioClient.getObject(build);

            File file = new File(fileName);
            String encodedFileName = URLEncoder.encode(file.getName(), "UTF-8");
            response.setContentType("application/octet-stream");

            response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"");
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = stream.read(buffer)) != -1) {
                response.getOutputStream().write(buffer, 0, bytesRead);
            }
            stream.close();

        } catch (MinioException e) {
            System.out.println("Error occurred: " + e);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
        }
    }


    public String uploadbinaryDataFileToMINIO(byte[] binaryData, String fileName) {


        try {
            minioClient.putObject(PutObjectArgs.builder()
                .bucket(minioProperties.getBucketName())
                .object(fileName)
                .stream(new java.io.ByteArrayInputStream(binaryData), binaryData.length, -1)
                .build());
            System.out.println("文件已成功上传到Minio");
        } catch (Exception e) {
            System.out.println("上传文件时出错: " + e.getMessage());
            e.printStackTrace();
        }
        return fileName;

    }


}
